﻿/*
 * SecureSession.h
 *
 */
#ifndef __GDK_SECURESESSION_H__
#define __GDK_SECURESESSION_H__

#include <gdk/core/Types.h>
#include <gdk/core/String.h>


namespace gdk
{



	class SecureSession
	{
		typedef ssize_t (Void::*Fread)(void *buf, ssize_t size);
		typedef ssize_t (Void::*Fwrite)(const void *data, ssize_t size);
		typedef String  (Void::*FgetUrl)(void) const;

	private:
		Void*		_object;
		Fread		_read;
		Fwrite		_write;
		FgetUrl		_getUrl;

	public:
		enum {
			BUFFERSIZE = 0x0000ffff,
		};
	private:

		//Cache的数据
		ssize_t		_packageSize;
		char		_packageCache[BUFFERSIZE];

		//发送的数据
		uint32_t	_writeCrc; //数据校验值
		uint32_t	_writeKey; //数据加密钥匙
		ssize_t		_writePointer;
		ssize_t		_writeDataSize;
		char		_writeBuffer
				[
					sizeof(uint16_t)+//useless
					sizeof(uint16_t)+//data size
					BUFFERSIZE+//data
					sizeof(uint32_t)+//crc
					sizeof(uint32_t)//useless
				];

		//接收的数据
		bool		_isReadKey;
		bool		_isReadable;
		uint32_t	_readCrc; //数据校验值
		uint32_t	_readKey; //数据加密钥匙
		ssize_t		_readPointer;
		ssize_t		_readDataSize;
		char		_readBuffer
					[
						sizeof(uint16_t) + //useless
						sizeof(uint16_t) + //data size
						BUFFERSIZE +       //data
						sizeof(uint32_t)   //crc
					];
		bool		_readError; //读数据错误

	private:
		void init(void);

	public:
		SecureSession(void);

	public:
		template<typename Tyclass> __INLINE__ void setUp
		(
			Tyclass *o,
			ssize_t (Tyclass::*r)(void *, ssize_t),
			ssize_t (Tyclass::*w)(const void *, ssize_t),
			String  (Tyclass::*u)(void) const
		)
		{
			struct {
				union {
					ssize_t (Tyclass::*r)(void *, ssize_t);
					ssize_t (Tyclass::*w)(const void *, ssize_t);
					String  (Tyclass::*u)(void) const;
					Fread	_read;
					Fwrite	_write;
					FgetUrl	_getUrl;
				};
			} i;

			_object = (Void*)o;
			i.r = r; _read   = i._read;
			i.w = w; _write  = i._write;
			i.u = u; _getUrl = i._getUrl;
		}

	public:
		ssize_t available(void) const;
		ssize_t peek(void *buf, ssize_t size) const;
		ssize_t read(void *buf, ssize_t size);
		ssize_t write(const void *data, ssize_t size);
		ssize_t flush(void);
		void    close(void);
	};





}//namespace gdk


#endif /*__GDK_SECURESESSION_H__*/
